﻿#include "kongming.h"
#include"GameModel.h"
#include<QPainter>
#include<QSound>
#include<math.h>
#include<QMouseEvent>
#include<QDialog>
#include<QDebug>
#include<QMessageBox>
#include<QMenuBar>
#include<QMenu>
#include<QMainWindow>
#include"start.h"
kongming::kongming(QWidget *parent) : QMainWindow(parent)//因为一开始此处继承的是Widget
{
    //设置返回 为啥有地方可以用有地方不可以用呢？！
    QMenuBar *bar = this->menuBar();
       this->setMenuBar(bar);
       QMenu * helpMenu = bar->addMenu("帮助");
       QAction *back = helpMenu->addAction("返回");//给菜单项下面再添加项目
       connect(back,&QAction::triggered,this,[=](){
           kongmingstartFace=new kongmingstart;
           this->hide();
           kongmingstartFace->show();
       });
    //设置窗口大小
    setFixedSize(MARGIN2*2+BLOCK_SIZE2*BOARD_GRAD_SIZE2,
                 MARGIN2*2+BLOCK_SIZE2*BOARD_GRAD_SIZE2);
    setMouseTracking(true);//调用鼠标移动监听
    //设置窗口标题
    setWindowTitle("孔明棋");
    //设置窗口图标
    setWindowIcon(QPixmap(":/pic/wolong.png"));
    initGame2();
}
void kongming::initGame2(){
    game=new GameModel;
    game->startGame2();
    update();
}
void kongming::paintEvent(QPaintEvent *){
    QPainter painter(this);

    //绘制背景
    QPixmap pix;
    pix.load(":/pic/background.png");
    painter.drawPixmap(0,0,this->width(),this->height(),pix);
    //绘制棋盘
    painter.setRenderHint(QPainter::Antialiasing,true);//抗锯齿
    for(int i=0;i<BOARD_GRAD_SIZE2+1;i++){
        //竖线
        //第一第二条与最后两条需要特殊处理
        if(i==0||i==1||i==BOARD_GRAD_SIZE2||i==BOARD_GRAD_SIZE2-1)
        painter.drawLine(MARGIN2+BLOCK_SIZE2*i,MARGIN2+2*BLOCK_SIZE2,MARGIN2+BLOCK_SIZE2*i,size().height()-MARGIN2-2*BLOCK_SIZE2);
        else
            painter.drawLine(MARGIN2+BLOCK_SIZE2*i,MARGIN2,MARGIN2+BLOCK_SIZE2*i,size().height()-MARGIN2);
        //此处size().height() 返回的是屏幕高度
        //横线
        if(i==0||i==1||i==BOARD_GRAD_SIZE2||i==BOARD_GRAD_SIZE2-1)
        painter.drawLine(MARGIN2+2*BLOCK_SIZE2,MARGIN2+BLOCK_SIZE2*i,size().width()-MARGIN2-2*BLOCK_SIZE2,MARGIN2+BLOCK_SIZE2*i);
        else
             painter.drawLine(MARGIN2,MARGIN2+BLOCK_SIZE2*i,size().width()-MARGIN2,MARGIN2+BLOCK_SIZE2*i);
    }
    //绘制选中点
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    //绘制棋盘自带棋子  (废案 此方法打印为静态)
//    brush.setColor(Qt::white);
//    painter.setBrush(brush);
//    for(int i=0;i<BOARD_GRAD_SIZE2;i++){
//        for(int p=0;p<BOARD_GRAD_SIZE2;p++){
//            if(i==3&&p==3)continue;//空出中间子
//            if(i==0||i==1||i==BOARD_GRAD_SIZE2-2||i==BOARD_GRAD_SIZE2-1){
//                if(p==2||p==3||p==4)
//                painter.drawEllipse(MARGIN2/2+BLOCK_SIZE2/2+BLOCK_SIZE2*p,
//                                   MARGIN2/2+BLOCK_SIZE2/2+BLOCK_SIZE2*i,
//                                    MARGIN2,MARGIN2);
//            }
//                else
//                painter.drawEllipse(MARGIN2/2+BLOCK_SIZE2/2+BLOCK_SIZE2*p,
//                                   MARGIN2/2+BLOCK_SIZE2/2+BLOCK_SIZE2*i,
//                                    MARGIN2,MARGIN2);

//        }
//    }

    //绘制落子标记(防止鼠标出框越界)
    if(clickPosRow>=0&&clickPosRow<BOARD_GRAD_SIZE2&&
            clickPosCol>=0&&clickPosCol<BOARD_GRAD_SIZE2&&
            game->gameMapVec[clickPosRow][clickPosCol]==-2){
        brush.setColor(Qt::blue);
        painter.setBrush(brush);
        //绘制矩形左上角x坐标 y坐标 长 宽
        painter.drawRect(MARGIN2+BLOCK_SIZE2/2+BLOCK_SIZE2*clickPosCol-MARK_SIZE2/2
                         ,MARGIN2+BLOCK_SIZE2/2+BLOCK_SIZE2*clickPosRow-MARK_SIZE2/2
                         ,Preview_MARGIN,Preview_MARGIN);
    }

    //绘制棋子
    for(int i=0;i<BOARD_GRAD_SIZE2;i++){
        for(int j=0;j<BOARD_GRAD_SIZE2;j++){
            if(game->gameMapVec[j][i]==1){
            brush.setColor(Qt::white);
            painter.setBrush(brush);
            painter.drawEllipse(MARGIN2/2+BLOCK_SIZE2/2+BLOCK_SIZE2*i,MARGIN2/2+BLOCK_SIZE2/2+BLOCK_SIZE2*j,MARGIN2,MARGIN2);
            }
        }
    }
    //判断分数
    if(game->judgeWin()){

        //结束音效

        //根据剩余棋子以评分
        QString str;
        int level=game->finalResult();
        switch (level) {
            case 1:str="天才";break;
            case 2:str="优秀";break;
            case 3:str="优良";break;
        }
        if(level>3&&level<=5)str="一般";
        if(level>5)str="新手";
        QMessageBox::StandardButton btnValue=QMessageBox::information(this,"结束","评分为:"+str);
        //重置游戏状态，否则容易死循环
        if(btnValue==QMessageBox::Ok){
            game->startGame2();
        }
        //重置
        game->startGame2();
    }
}
void kongming::mouseMoveEvent(QMouseEvent * event){
    //通过鼠标的靠近判断落子标记
    int x=event->x();
    int y=event->y();

    //棋盘边缘不能落子 当落子在棋盘范围内才执行
    if(x>=MARGIN2+BLOCK_SIZE2/2&&
            x<size().width()-MARGIN2-BLOCK_SIZE2/2&&
            y>=MARGIN2+BLOCK_SIZE2/2&&
            y<size().height()-MARGIN2-BLOCK_SIZE2/2){
        //获取一个最近的左上角的点
        //add by rock
        int col=(x-MARGIN2-BLOCK_SIZE2/2)/BLOCK_SIZE2;
        int row=(y-MARGIN2-BLOCK_SIZE2/2)/BLOCK_SIZE2;

        int leftTopPosX=MARGIN2+BLOCK_SIZE2/2+BLOCK_SIZE2*col;
        int leftTopPosY=MARGIN2+BLOCK_SIZE2/2+BLOCK_SIZE2*row;

        //根据 距离算出合适的点击位置，一共四个点，根据半径距离选择最近的
        clickPosRow=-1;
        clickPosCol=-1;
        int len=0;//计算完后取整

         selectPos=false;

         //左上角   确定一个误差在范围内的点，且只能确定一个
         len=sqrt(pow((x-leftTopPosX),2)+pow((y-leftTopPosY),2));
         if(len<POS_OFFSET2){
             clickPosRow=row;
             clickPosCol=col;
             //只有在该位置没棋子的时候才能下
//             if(game->gameMapVec[clickPosRow][clickPosCol]==-2){
//                 selectPos=true;
//             }
         }
         //判断右上角
         len=sqrt(pow((x-leftTopPosX-BLOCK_SIZE2),2)+pow((y-leftTopPosY),2));
         if(len<POS_OFFSET2){
             clickPosRow=row;
             clickPosCol=col+1;

//             if(game->gameMapVec[clickPosRow][clickPosCol]==-2){
//                 selectPos=true;
//             }
         }
         //判断左下角
         len=sqrt(pow((x-leftTopPosX),2)+pow((y-leftTopPosY-BLOCK_SIZE2),2));
         if(len<POS_OFFSET2){
             clickPosRow=row+1;
             clickPosCol=col;

//             if(game->gameMapVec[clickPosRow][clickPosCol]==-2){
//                 selectPos=true;
//             }
         }
         //判断右下角
         len=sqrt(pow((x-leftTopPosX-BLOCK_SIZE2),2)+pow((y-leftTopPosY-BLOCK_SIZE2),2));
         if(len<POS_OFFSET2){
             clickPosRow=row+1;
             clickPosCol=col+1;

//             if(game->gameMapVec[clickPosRow][clickPosCol]==-2){
//                 selectPos=true;
//             }
        }
    }
    //确定了一个点后 刷新 调用绘图
    if(clickPosRow==-1&&clickPosCol==-1)return;

    update();
}
//鼠标松开
//void kongming::mouseReleaseEvent(QMouseEvent *){

//    if(selectPos==false){//如果没有选成功即位置不恰当，就返回重选
//        return;
//    }else{
//        //如果选成功 在落子成功之前，要把落子标记重新设置为false，为下一次做准备
//        selectPos=false;
//    }

//    //"下"一个人选定的棋子
//    chessOneByPerson3();

//}
//选中一个要移动的子
void kongming::mousePressEvent(QMouseEvent* event){
    int x=event->x();
    int y=event->y();
    if(x>=MARGIN2+BLOCK_SIZE2/2&&
            x<size().width()-MARGIN2-BLOCK_SIZE2/2&&
            y>=MARGIN2+BLOCK_SIZE2/2&&
            y<size().height()-MARGIN2-BLOCK_SIZE2/2){
        //获取一个最近的左上角的点
        //add by rock
        int col=(x-MARGIN2-BLOCK_SIZE2/2)/BLOCK_SIZE2;
        int row=(y-MARGIN2-BLOCK_SIZE2/2)/BLOCK_SIZE2;

        int leftTopPosX=MARGIN2+BLOCK_SIZE2/2+BLOCK_SIZE2*col;
        int leftTopPosY=MARGIN2+BLOCK_SIZE2/2+BLOCK_SIZE2*row;

        //根据 距离算出合适的点击位置，一共四个点，根据半径距离选择最近的
        clickPosR=-1;
        clickPosC=-1;
        int len=0;//计算完后取整

         selectPos=false;

         //左上角   确定一个误差在范围内的点，且只能确定一个
         len=sqrt(pow((x-leftTopPosX),2)+pow((y-leftTopPosY),2));
         if(len<POS_OFFSET2){
             clickPosR=row;
             clickPosC=col;
             //只有在该位置没棋子的时候才能下
//             if(game->gameMapVec[clickPosR][clickPosC]==1){
//                 selectPos=true;
//             }
         }
         //判断右上角
         len=sqrt(pow((x-leftTopPosX-BLOCK_SIZE2),2)+pow((y-leftTopPosY),2));
         if(len<POS_OFFSET2){
             clickPosR=row;
             clickPosC=col+1;

//             if(game->gameMapVec[clickPosR][clickPosC]==1){
//                 selectPos=true;
//             }
         }
         //判断左下角
         len=sqrt(pow((x-leftTopPosX),2)+pow((y-leftTopPosY-BLOCK_SIZE2),2));
         if(len<POS_OFFSET2){
             clickPosR=row+1;
             clickPosC=col;

//             if(game->gameMapVec[clickPosR][clickPosC]==1){
//                 selectPos=true;
//             }
         }
         //判断右下角
         len=sqrt(pow((x-leftTopPosX-BLOCK_SIZE2),2)+pow((y-leftTopPosY-BLOCK_SIZE2),2));
         if(len<POS_OFFSET2){
             clickPosR=row+1;
             clickPosC=col+1;

//             if(game->gameMapVec[clickPosR][clickPosC]==1){
//                 selectPos=true;
//             }
        }
         qDebug()<<"点击位置为"<<clickPosR<<clickPosC;
         qDebug()<<"上次坐标为"<<pre_clickPosR<<pre_clickPosC;
         if(clickPosC==-1&&clickPosR==-1){
             return;
         }
         //if(game->gameMapVec[clickPosR][clickPosC]==1){qDebug()<<"1";}
         if(game->gameMapVec[clickPosR][clickPosC]==1&&game->gameMapVec[pre_clickPosR][pre_clickPosC]==1){
             game->sameLocate(pre_clickPosR,pre_clickPosC);
             pre_clickPosR=0;
             pre_clickPosC=0;
             return;
         }
         chessOneByPerson3();
}
    //qDebug()<<clickPosC<<clickPosR;

    update();
}
void kongming::chessOneByPerson(){
    //根据当前存储的坐标下子
    //只有有效点击才下子，而且该处没有子
    if(clickPosR!=-1&&clickPosC!=-1&&
            game->gameMapVec[clickPosR][clickPosC]==-2){
        //在游戏的数据模型中落子
        game->actionByPerson2(clickPosR,clickPosC);
        //开始处理烂摊子
         game->treatPreLocate(pre_clickPosR,pre_clickPosC,clickPosR,clickPosC);
        //播放落子音效
        QSound* personChessOne=new QSound(":/pic/stone.wav",this);
        personChessOne->play();
        //重绘
        update();
    }
}
void kongming::getPreLocate(){
    pre_clickPosR=clickPosR;
    pre_clickPosC=clickPosC;
    //qDebug()<<"得到上个点坐标"<<pre_clickPosR<<pre_clickPosC;
}
void kongming::chessOneByPerson3(){
    //下一次棋后还需初始化 四个位置与预移动点坐标
    //在点击落子位置前记录一次上次点击的坐标
    if(game->gameMapVec[clickPosR][clickPosC]==1){
        //在周围寻找能下的子
        game->findDropLocation(clickPosR,clickPosC);
        getPreLocate();
    }
    if(game->gameMapVec[clickPosR][clickPosC]==-2){
        //先落下玩家下的子
        chessOneByPerson();
    }
}
void kongming::getInitialP(int row,int col){
    game->initialPieceY=row;
    game->initialPieceX=col;
}
